using System;
using System.Collections.Generic;
using UnityEngine;

public static class MathEx
{
	public struct QuadraticRoots
	{
		public float minusRoot;

		public float plusRoot;

		public bool foundRealRoots;
	}

	[Serializable]
	public class Range
	{
		public float min;

		public float max;

		public float avg
		{
			get
			{
				return (min + max) * 0.5f;
			}
		}

		public float Lerp(float value)
		{
			return min + (max - min) * value;
		}

		public float InverseLerp(float value)
		{
			if (max - min == 0f)
			{
				return 0f;
			}
			return Mathf.Clamp01((value - min) / (max - min));
		}

		public float Random()
		{
			return UnityEngine.Random.Range(min, max);
		}

		public Range Clone()
		{
			Range range = new Range();
			range.min = min;
			range.max = max;
			return range;
		}
	}

	public class NullPoints
	{
		public List<float> nullPts = new List<float>();

		public NullPoints onlyPositive
		{
			get
			{
				NullPoints nullPoints = new NullPoints();
				foreach (float nullPt in nullPts)
				{
					if (nullPt >= 0f)
					{
						nullPoints.nullPts.Add(nullPt);
					}
				}
				return nullPoints;
			}
		}

		public float Min
		{
			get
			{
				if (nullPts.Count == 2)
				{
					return Mathf.Min(nullPts[0], nullPts[1]);
				}
				if (nullPts.Count == 1)
				{
					return nullPts[0];
				}
				return 0f;
			}
		}

		public float Max
		{
			get
			{
				if (nullPts.Count == 2)
				{
					return Mathf.Max(nullPts[0], nullPts[1]);
				}
				if (nullPts.Count == 1)
				{
					return nullPts[0];
				}
				return 0f;
			}
		}

		public NullPoints Clamp(float min, float max)
		{
			NullPoints nullPoints = new NullPoints();
			foreach (float nullPt in nullPts)
			{
				if (nullPt >= min && nullPt <= max)
				{
					nullPoints.nullPts.Add(nullPt);
				}
			}
			return nullPoints;
		}
	}

	public static float MapFromRangeToRange(float fromRangeFrom, float fromRangeTo, float toRangeFrom, float toRangeTo, float value)
	{
		return Mathf.Lerp(toRangeFrom, toRangeTo, Mathf.InverseLerp(fromRangeFrom, fromRangeTo, value));
	}

	public static float SubstractAngle(float angle1, float angle2)
	{
		return AbsMin(angle1 + 360f - angle2, angle1 - (angle2 + 360f), angle1 - angle2);
	}

	public static float AbsMin(float a, float b)
	{
		return (!(Mathf.Abs(a) < Mathf.Abs(b))) ? b : a;
	}

	public static float AbsMin(float a, float b, float c)
	{
		return (Mathf.Abs(a) < Mathf.Abs(b)) ? ((!(Mathf.Abs(a) < Mathf.Abs(c))) ? c : a) : ((!(Mathf.Abs(b) < Mathf.Abs(c))) ? c : b);
	}

	public static float Min(float a, float b)
	{
		return (!(a < b)) ? b : a;
	}

	public static int Min(int a, int b)
	{
		return (a >= b) ? b : a;
	}

	public static int ArithmeticSum(int a, int d, int n)
	{
		return n * (2 * a + (n - 1) * d) / 2;
	}

	public static float Max(float a, float b)
	{
		return (!(a > b)) ? b : a;
	}

	public static int Max(int a, int b)
	{
		return (a <= b) ? b : a;
	}

	public static float Min(float a, float b, float c)
	{
		return (a < b) ? ((!(a < c)) ? c : a) : ((!(b < c)) ? c : b);
	}

	public static float Max(float a, float b, float c)
	{
		return (a > b) ? ((!(a > c)) ? c : a) : ((!(b > c)) ? c : b);
	}

	public static void Swap(ref float a, ref float b)
	{
		float num = a;
		a = b;
		b = a;
	}

	public static float CatmullRomInverseLerp(float p1, float p2, float p3, float p4, float searchedValue, float guess)
	{
		for (int i = 0; i < 7; i++)
		{
			float num = CatmullRomLerp(p1, p2, p3, p4, guess) - searchedValue;
			float num2 = CatmullRomLerpDerivative(p1, p2, p3, p4, guess);
			guess = Mathf.Clamp01(guess - num / num2);
		}
		return guess;
	}

	public static float CatmullRomLerpDerivative(float p1, float p2, float p3, float p4, float t)
	{
		float num = t * t;
		float num2 = -3f * num + 4f * t - 1f;
		float num3 = 6f * num - 10f * t;
		float num4 = -9f * num + 8f * t + 1f;
		float num5 = 3f * num - 2f * t;
		float num6 = 0.5f;
		return num6 * (num2 * p1 + num3 * p2 + num4 * p3 + num5 * p4);
	}

	public static float CatmullRomLerp(float p1, float p2, float p3, float p4, float t)
	{
		float num = t * t;
		float num2 = t * t * t;
		float num3 = -1f * num2 + 2f * num - t;
		float num4 = 3f * num2 - 5f * num + 2f;
		float num5 = -3f * num2 + 4f * num + t;
		float num6 = num2 - num;
		float num7 = 0.5f;
		return num7 * (num3 * p1 + num4 * p2 + num5 * p3 + num6 * p4);
	}

	public static int SignZeroPositive(float value)
	{
		return (!(value < 0f)) ? 1 : (-1);
	}

	public static int SignWithZero(float value)
	{
		if (value == 0f)
		{
			return 0;
		}
		return SignZeroPositive(value);
	}

	public static float Hermite(float moveTime)
	{
		moveTime = Mathf.Clamp01(moveTime);
		return moveTime * moveTime * (3f - 2f * moveTime);
	}

	public static float PingPong(float val)
	{
		val -= Mathf.Floor(val);
		if (val <= 0.5f)
		{
			return val * 2f;
		}
		return 1f - val * 2f;
	}

	public static float Avg(params float[] avg)
	{
		float num = 0f;
		if (avg.Length == 0)
		{
			return 0f;
		}
		foreach (float num2 in avg)
		{
			num += num2;
		}
		return num / (float)avg.Length;
	}

	public static NullPoints FindParabolaNullPoints(float a, float b, float c)
	{
		NullPoints nullPoints = new NullPoints();
		if (a == 0f)
		{
			nullPoints.nullPts.Add((0f - c) / b);
			return nullPoints;
		}
		float num = b * b - 4f * a * c;
		if (num < 0f)
		{
			return nullPoints;
		}
		num = Mathf.Sqrt(num);
		nullPoints.nullPts.Add((0f - b + num) / (2f * a));
		nullPoints.nullPts.Add((0f - b - num) / (2f * a));
		return nullPoints;
	}
}
